In [12]:
# these imports let you use opencv
import cv2 #opencv itself
import common #some useful opencv functions
import video # some video stuff
import numpy as np # matrix manipulations
#the following are to do with this interactive notebook code
%matplotlib inline
from matplotlib import pyplot as plt # this lets you draw inline pictures in the notebooks
import pylab # this allows you to control figure size
pylab.rcParams['figure.figsize'] = (10.0, 8.0) # this controls figure size in the notebook
input_image=cv2.imread('noidea.jpg')
In [13]:
flipped_code_0=cv2.flip(input_image,0) # vertical flip
plt.imshow(flipped_code_0)
Out[13]:
In [14]:
flipped_code_1=cv2.flip(input_image,1) # horizontal flip
plt.imshow(flipped_code_1)
Out[14]:
In [15]:
transposed=cv2.transpose(input_image)
plt.imshow(transposed)
Out[15]:
To find the min or max of a matrix, you can use minMaxLoc. This takes a single channel image (it doesn't make much sense to take the max of a 3 channel image). So in the next code snippet you see a for loop, using python style image slicing, to look at each channel of the input image separately.
In [16]:
for i in range(0,3):
min_value, max_value, min_location, max_location=cv2.minMaxLoc(input_image[:,:,i])
print "min {} is at {}, and max {} is at {}".format(min_value, min_location, max_value, max_location)
OpenCV has a lot of functions for doing mathematics on images. Some of these have "analogous" numpy alternatives, but it is nearly always better to use the OpenCV version. The reason for this that OpenCV is designed to work on images and so handles overflow better (OpenCV add, for example, truncates to 255 if the datatype is image-like and 8 bit; Numpy's alternative wraps around).
Useful arithmetic operations include add and addWeighted, which combine two images that are the same size.
In [17]:
#First create an image the same size as our input
blank_image = np.zeros((input_image.shape), np.uint8)
blank_image[100:200,100:200,1]=100; #give it a green square
new_image=cv2.add(blank_image,input_image) # add the two images together
plt.imshow(cv2.cvtColor(new_image, cv2.COLOR_BGR2RGB))
Out[17]:
In [18]:
d=3
img_blur3 = cv2.GaussianBlur(input_image, (2*d+1, 2*d+1), -1)[d:-d,d:-d]
plt.imshow(cv2.cvtColor(img_blur3, cv2.COLOR_BGR2RGB))
Out[18]:
In [19]:
d=5
img_blur5 = cv2.GaussianBlur(input_image, (2*d+1, 2*d+1), -1)[d:-d,d:-d]
plt.imshow(cv2.cvtColor(img_blur5, cv2.COLOR_BGR2RGB))
Out[19]:
In [20]:
d=15
img_blur15 = cv2.GaussianBlur(input_image, (2*d+1, 2*d+1), -1)[d:-d,d:-d]
plt.imshow(cv2.cvtColor(img_blur15, cv2.COLOR_BGR2RGB))
Out[20]:
Edge detection is the final image processing technique we're going to look at in this tutorial.
For a lot of what we think of as "modern" computer vision techniques, edge detection functions as a building block. Much edge detection actually works by convolution, and indeed convolutional neural networks are absolutely the flavour of the month in some parts of computer vision. Sobel's edge detector was one of the first truly successful edge detection (enhancement) technique and that involves convolution at its core. You can read more about the background to Sobel here in the OpenCV docs [http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_imgproc/py_gradients/py_gradients.html].
In [21]:
sobelimage=cv2.cvtColor(input_image,cv2.COLOR_BGR2GRAY)
sobelx = cv2.Sobel(sobelimage,cv2.CV_64F,1,0,ksize=9)
sobely = cv2.Sobel(sobelimage,cv2.CV_64F,0,1,ksize=9)
plt.imshow(sobelx,cmap = 'gray')
# Sobel works in x and in y, change sobelx to sobely in the olt line above to see the difference
Out[21]:
Canny edge detection is another winnning technique - it takes two thresholds. The first one determines how likely Canny is to find an edge, and the second determines how likely it is to follow that edge once it's found. Investigate the effect of these thresholds by altering the values below.
In [22]:
th1=30
th2=60 # Canny recommends threshold 2 is 3 times threshold 1 - you could try experimenting with this...
d=3 # gaussian blur
edgeresult=input_image.copy()
edgeresult = cv2.GaussianBlur(edgeresult, (2*d+1, 2*d+1), -1)[d:-d,d:-d]
gray = cv2.cvtColor(edgeresult, cv2.COLOR_BGR2GRAY)
edge = cv2.Canny(gray, th1, th2)
edgeresult[edge != 0] = (0, 255, 0) # this takes pixels in edgeresult where edge non-zero colours them bright green
plt.imshow(cv2.cvtColor(edgeresult, cv2.COLOR_BGR2RGB))
Out[22]:
In [ ]: